package com.example.android_app;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.VideoView;

import androidx.activity.EdgeToEdge;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
//import org.json.JSONObject;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.ListIterator;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainActivity extends Activity {
    //服务器url,请更改为您的服务器地址
    private String serverUrl="http://192.168.1.107:8080";
    //播放素材列表，列表中单个元素格式：{"playDuration":10,"playOrder":1,"materialId":1,"type":1,"materialName":"大风","uri":"http://127.0.0.1:9300/statics/2025/06/04/小电影_20250604125732A018.mp4"}
    private LinkedList<String> linkedList = new LinkedList<>();
    //从服务器下载的素材列表，下载完成之后，让 linkedList=newLinkedList
    private LinkedList<String> newLinkedList = new LinkedList<>();
    //当前播放素材的索引
    private int curIndex=-1;
    private OkHttpClient client = new OkHttpClient();
    //设备唯一序列号
    private String serialNumber;
    private Handler handler = new Handler();
    private int errorWait=100;
    //轮询服务器间隔时间，单位毫秒
    private int registInterval=60000;
    //播放素材列表数据保存在此文件中
    private String saveFileName="filesConfig";
    //轮询服务器时，使用的参数
    private String registJson;





    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            // 在延迟时间后执行的任务代码
            Log.d("Handler", "Delayed work is executed.");
            work();
        }
    };

    private Runnable registRunnable = new Runnable() {
        @Override
        public void run() {
            // 在延迟时间后执行的任务代码
            Log.d("Handler", "Delayed regist is executed.");
            register(serverUrl+"/screen/device/register" ,registJson);
        }
    };

    /**
     *在广告屏上显示素材内容
     */
    private void work(){
        FileInputStream fis=null;
        try {
            if (linkedList.size() > 0) {
                curIndex++;
                if (curIndex >= linkedList.size()) {
                    curIndex = 0;
                }
                JSONObject jsonFile = new JSONObject(linkedList.get(curIndex));
                int type = jsonFile.getInt("type");

                if (type == 0) {//图片
                    int duration=jsonFile.getInt("playDuration");
                    File imgFile = new File(getExternalFilesDir(
                            null), "datas/"+jsonFile.getString("fileName"));
                    fis = new FileInputStream(imgFile);
                    //使用 BitmapFactory 的 decodeStream 将图片的输入流直接转换为 Bitmap
                    final Bitmap bitmap = BitmapFactory.decodeStream(fis);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                ImageView imageView = (ImageView) findViewById(R.id.imageView);
                                imageView.setImageBitmap(bitmap);

                                TextView multilineText = (TextView) findViewById(R.id.editTextTextMultiLine);
                                multilineText.setVisibility(View.GONE);

                                VideoView videoView = (VideoView) findViewById(R.id.videoView);
                                videoView.setVisibility(View.GONE);


                                imageView.setVisibility(View.VISIBLE);

                                handler.postDelayed(runnable,duration*1000);

                            } catch (Exception ex) {
                                Log.e("TAG", "------------" + ex.getMessage());
                                handler.postDelayed(runnable,errorWait);
                            }


                        }
                    });
                }else if(type==1){//视频
                    //加载指定的视频文件
                    File videoFile = new File(getExternalFilesDir(
                            null), "datas/"+jsonFile.getString("fileName"));
                    VideoView videoView = (VideoView) findViewById(R.id.videoView);
                    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
                    layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                    layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
                    layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
                    layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                    videoView.setLayoutParams(layoutParams);
                    videoView.setVideoPath(videoFile.getAbsolutePath());
                    videoView.setVisibility(View.VISIBLE);

                    //让VideoView获取焦点
                    videoView.requestFocus();
                    videoView.start();


                }
            }
        }catch(Exception exWork){
            Log.e("TAG",exWork.getMessage());
            handler.postDelayed(runnable,errorWait);
        }finally {
            closeStream(fis);
        }
    }

    /**
     * 打印素材列表的内容
     */
    private void logLinkedList(){
        //使用迭代器遍历——正向遍历
        ListIterator<String> it = linkedList.listIterator();
        while (it.hasNext()) {
            Log.i("TAG",it.next().toString()+" ");
        }
    }

    /**
     * 下载素材，并加入newLinkedList
     * @param jsonFile 单个素材信息
     */
    private void doJsonFile(JSONObject jsonFile) {
        InputStream is=null;
        FileOutputStream fos=null;
        try {
            String url = jsonFile.getString("uri");
            String fileName = url;
            int index = url.lastIndexOf("/");

            if (index != -1) {
                fileName = url.substring(index + 1);
            }
            jsonFile.put("fileName", fileName);


            File file = new File(getExternalFilesDir(
                    null), "datas/"+fileName);

            if(!file.exists()) {
                Log.i("TAG","Begin download");
                //1.创建OkHttpClient对象
                OkHttpClient okHttpClient = new OkHttpClient();
                //2.创建Request对象，设置一个url地址（百度地址）,设置请求方式。
                Request request = new Request.Builder().url(serverUrl + url).get().build();
                //3.创建一个call对象,参数就是Request请求对象
                Call call = okHttpClient.newCall(request);

                Response response = call.execute();
                //拿到字节流
                is = response.body().byteStream();
                int len = 0;
                //设置下载图片存储路径和名称
                fos = new FileOutputStream(file);
                byte[] buf = new byte[10240];
                while ((len = is.read(buf)) != -1) {
                    fos.write(buf, 0, len);
                    Log.e("TAG", "onResponse: " + len);
                }
                fos.flush();

            }else{
                Log.i("TAG","need not download");
            }
            addLinkedList(newLinkedList,jsonFile);

        }catch(Exception ex){
            Log.e("TAG",ex.getMessage());
        }finally {
            closeStream(fos);
            closeStream(is);

        }
    }

    /**
     * 获取设备唯一标识
     * @return 设备唯一标识
     */
    private String getSerialNumber(){
        String serial = Build.SERIAL;
        Log.i("TAG","serial:"+serial);
        String androidId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
        Log.i("TAG","androidId"+androidId);
        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        String macAddress = wifiManager.getConnectionInfo().getMacAddress();
        Log.i("TAG","macAddress"+macAddress);
        String uniqueIdentifier = serial + macAddress + androidId;
        if(uniqueIdentifier.length()>255) {
            uniqueIdentifier = uniqueIdentifier.substring(0, 255);
        }
        return uniqueIdentifier;
    }

    /**
     * 显示文本信息
     * @param message 信息内容
     */
    private void showMessage(String message){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {


                TextView multilineText = (TextView) findViewById(R.id.editTextTextMultiLine);
                multilineText.setText(message);

                ImageView imageView=(ImageView) findViewById(R.id.imageView);
                imageView.setVisibility(View.GONE);
                VideoView videoView = (VideoView) findViewById(R.id.videoView);
                //if(videoView.isPlaying()){
                try {
                    videoView.stopPlayback();
                }catch (Exception e){

                }
                //}
                videoView.setVisibility(View.GONE);

                multilineText.setVisibility(View.VISIBLE);
            }
        });
    }

    /**
     * 把素材加入链表中
     * @param linkedList  链表
     * @param JSONObject  素材
     */
    private void addLinkedList(LinkedList<String> linkedList,JSONObject JSONObject){
        try{
            double playOrder=JSONObject.getDouble("playOrder");
            if(linkedList.size()==0){
                linkedList.add(JSONObject.toString());
                return;
            }
            for(int i=0;i<linkedList.size();i++){
                JSONObject t=new JSONObject(linkedList.get(i));
                if(playOrder<t.getDouble("playOrder")){
                    linkedList.add(i,JSONObject.toString());
                    return;
                }

            }
            linkedList.add(JSONObject.toString());
        }catch (Exception e){
            e.printStackTrace();
            Log.i("TAG",e.getMessage());
        }
    }

    /**
     * 关闭流
     * @param t 流
     */
    private void closeStream(Closeable t){
        try {
            if(t!=null) {
                t.close();
            }
        }catch(Exception e){

        }
    }

    /**
     * 从文件中取出素材列表linkedList
     * @param fileName 文件名
     */
    public void  getLinkedList(String fileName) //存数据
    {
        FileInputStream fis=null;
        ObjectInputStream ois=null;
        try {

            File file = new File(getExternalFilesDir(
                    null), fileName);
            if(file.exists()) {
                fis = new FileInputStream(file);
                ois = new ObjectInputStream(fis);
                linkedList = (LinkedList<String>) ois.readObject();


            }
        }catch (Exception e){
            e.printStackTrace();
            Log.i("TAG","read linkedlist error:"+e.getMessage());


        }finally {
            closeStream(ois);
            closeStream(fis);

        }


    }

    /**
     * 把素材列表内容写入文件中
     * @param list  素材列表
     * @param fileName 文件名
     * @throws Exception 抛出异常
     */
    public void saveLinkedList(LinkedList<String> list,String fileName) throws Exception
    {

        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            File file = new File(getExternalFilesDir(
                    null), fileName);
            fos = new FileOutputStream(file);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(list);
        }catch(Exception e){
            throw e;
        }finally {
            closeStream(oos);
            closeStream(fos);
        }




    }

    /**
     * 从服务器获取设备播放素材列表
     * @param url 服务器地址
     * @param jsonString 请求参数，主要包括设备唯一标识
     */
    private void register(String url,String jsonString){
        try {
            MediaType mediaType = MediaType.parse("application/json; charset=utf-8");//"类型,字节码"

            //1.创建OkHttpClient对象
            OkHttpClient okHttpClient = new OkHttpClient();
            //2.通过RequestBody.create 创建requestBody对象
            RequestBody requestBody = RequestBody.create(mediaType, jsonString);
            //3.创建Request对象，设置URL地址，将RequestBody作为post方法的参数传入
            Request request = new Request.Builder().url(url).post(requestBody).build();
            //4.创建一个call对象,参数就是Request请求对象
            Call call = okHttpClient.newCall(request);
            //5.请求加入调度,重写回调方法
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    Log.e("TAG", e.toString());
                    handler.postDelayed(registRunnable, registInterval);
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String returnMessage = response.body().string();
                    Log.i("TAG", "@@@@@@@@@@@@@register@@@@@@@@@@@" + returnMessage);
                    try {
                        JSONObject JSONObject = new JSONObject
                                (returnMessage);
                        int code = JSONObject.getInt("code");
                        if (code != 200) {
                            String message = JSONObject.getString("msg");
                            if(linkedList.size()==0) {
                                showMessage(message);
                            }
                            return;
                        }
                        JSONObject jsonData =
                                JSONObject.getJSONObject("data");
                        JSONArray jsonFiles = jsonData.getJSONArray("files");
                        if (jsonFiles.length() > 0) {
                            newLinkedList.clear();
                            int len = jsonFiles.length();
                            for (int i = 0; i < len; i++) {
                                JSONObject file = (JSONObject) jsonFiles.get(i);
                                Log.i("TAG", file.toString());
                                doJsonFile(file);

                            }
                            logLinkedList();
                            if (!newLinkedList.equals(linkedList)) {
                                Log.i("TAG", "newLinkedList <> linkedList ");
                                saveLinkedList(newLinkedList, saveFileName);
                                int count = linkedList.size();
                                linkedList = newLinkedList;
                                if (count == 0) {//说明work方法没有启动
                                    handler.postDelayed(runnable, errorWait); //启动work方法
                                }
                            } else {
                                Log.i("TAG", "newLinkedList = linkedList ");
                            }


                        } else {
                            linkedList.clear();
                            newLinkedList.clear();

                            Long id = jsonData.getLong("deviceId");
                            String message = "设备编号为: " + id + " ，请联系管理员，为设备增加播放素材！";

                            showMessage(message);
                            saveLinkedList(newLinkedList,saveFileName);
                        }


                    } catch (Exception e) {
                        e.printStackTrace();
                        Log.i("TAG", e.getMessage());
                        if (linkedList.size() == 0) {
                            showMessage("系统出现一点小差错：" + e.getMessage());
                        }
                    }finally {
                        handler.postDelayed(registRunnable, registInterval);
                    }

                }
            });
        }catch(Exception ex){
            ex.printStackTrace();
            Log.i("TAG", ex.getMessage());
            handler.postDelayed(registRunnable, registInterval);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 获取应用的外部文件目录
        File folder = new File(getExternalFilesDir(null), "datas");
        // 创建文件夹
        if (!folder.exists()) {
            folder.mkdirs();
        }
        // 检查文件夹是否创建成功
        if (folder.exists()) {
            Log.i("TAG", "文件夹datas创建成功");
        } else {
            Log.i("TAG", "文件夹datas创建失败");

        }
        getLinkedList(saveFileName);
        try {
            if (linkedList.size() > 0) {
                handler.postDelayed(runnable, 1);//启动work方法
                //linkedList中的文件名加入stringSet
                HashSet<String> stringSet = new HashSet<>();
                ListIterator<String> it = linkedList.listIterator();
                while (it.hasNext()) {
                    String element=it.next().toString();
                    Log.i("TAG", element);
                    JSONObject j = new JSONObject(element);
                    stringSet.add(j.getString("fileName"));

                }


                //删除不用的素材文件
                File[] files = folder.listFiles();
                for (File file : files) {
                    // 对于每个文件和文件夹进行操作
                    if (file.isFile()) {
                        // 当前为文件，进行文件操作
                        if(!stringSet.contains(file.getName())){ //文件没在linkedList中
                            Log.i("TAG","删除文件："+file.getName());
                            file.delete();
                        }
                    }
                }
            } else {  //没有设置任何素材，删除所有文件
                File[] files = folder.listFiles();
                for (File file : files) {
                    // 对于每个文件和文件夹进行操作
                    if (file.isFile()) {
                        Log.i("TAG","删除文件："+file.getName());
                        file.delete();
                    }
                }
            }
        }catch (Exception ex){
            ex.printStackTrace();
            Log.i("TAG",ex.getMessage());
        }

        //EdgeToEdge.enable(this);
        //全屏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        decorView.setSystemUiVisibility(uiOptions);
        setContentView(R.layout.activity_main);
        /*
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        */

        VideoView videoView=(VideoView)findViewById(R.id.videoView);
        //不显示videoView的错误
        videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                return true;
            }
        });
        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {

                            ImageView imageView = (ImageView) findViewById(R.id.imageView);
                            imageView.setVisibility(View.GONE);

                            TextView multilineText = (TextView) findViewById(R.id.editTextTextMultiLine);
                            multilineText.setVisibility(View.GONE);

                            videoView.setVisibility(View.VISIBLE);
                            videoView.requestFocus();
                        } catch (Exception ex) {
                            Log.e("TAG", "------------" + ex.getMessage());
                            handler.postDelayed(runnable,errorWait);
                        }
                    }
                });
            }
        });
        //视频播放结束
        videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                // 在这里处理视频播放完毕后的逻辑
                videoView.stopPlayback();
                handler.postDelayed(runnable,1);
            }
        });

        Date date=new Date();
        Long timestamp=date.getTime();
        System.out.println(timestamp.toString());
        serialNumber=getSerialNumber();
        registJson = "{\"t\":" + timestamp.toString() + ","
                + "\"serial\":\"" + serialNumber + "\""
                + "}";
        register(serverUrl+"/screen/device/register" ,registJson);
    }
}